import { HttpService } from '@nestjs/axios';
import { Inject, Injectable } from '@nestjs/common';
import { WechatConfig } from './type/WechatConfig';
const WxPay = require('wechatpay-node-v3')
import * as url from 'url'

@Injectable()
export class WechatService {
	constructor(
		@Inject('WECHAT_CONFIG') private config:WechatConfig,
        private readonly http:HttpService,
    ){}

	async login(code:string) {
        const res = await this.http.axiosRef.get('https://api.weixin.qq.com/sns/jscode2session', {
            params : {
                appid : this.config.appid,
                secret : this.config.secret,
                grant_type : 'authorization_code',
                js_code : code
            }
        })

        return res.statusText == 'OK' ? res.data : null
    }

	//获取手机号码
    async getuserphonenumber(code:string, accessToken:string) {
        try {
            const res = await this.http.axiosRef.post('https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=' + accessToken, {
                code
            })
            if(res.statusText == 'OK' && res.data) {
                if(res.data.errcode == 0) {
                    return res.data.phone_info.phoneNumber
                }
            }


        } catch (error) {
            console.log(error.message)
        }
        
        return null
    }

	async getWXAccessToken() {
		const res = await this.http.axiosRef.get('https://api.weixin.qq.com/cgi-bin/token', {
            params : {
                grant_type : 'client_credential',
                appid : this.config.appid,
                secret : this.config.secret
            }
        })


        if(res.statusText == 'OK') {
            if(res.data && res.data.access_token) {
				return res.data.access_token
            }else {
                console.log(res.data)
            }
        }

		return null
	}

	//回调解密
    async decipher_gcm(ciphertext, associated_data, nonce) {
        const pay = new WxPay({
            appid: this.config.appid,
            mchid: this.config.mchid,
            publicKey: Buffer.from(this.config.publicKey, 'utf-8'), // 公钥
            privateKey: Buffer.from(this.config.privateKey, 'utf-8'), // 秘钥
        });

        return pay.decipher_gcm(ciphertext, associated_data, nonce, this.config.v3Key);
    }


    //小程序下单
    async pay(amount:number, orderNo:string, openid:string, description:string, notify_url:string) {
        const pay = new WxPay({
            appid: this.config.appid,
            mchid: this.config.mchid,
            publicKey: Buffer.from(this.config.publicKey, 'utf-8'), // 公钥
            privateKey: Buffer.from(this.config.privateKey, 'utf-8'), // 秘钥
        });

        let baseNotifyUrl = this.config.baseNotifyUrl
        if(baseNotifyUrl.endsWith('/') == false) {
            baseNotifyUrl += '/'
        }

        let result = await pay.transactions_jsapi({
            description: description,
            out_trade_no: orderNo,
            notify_url: url.resolve(baseNotifyUrl, notify_url),
            amount: {
              total: amount * 100,
            },
            payer: {
              openid: openid,
            }
        })



        if(result.status != 200) return null
        
        if(result.data) {
            result = result.data
        }


        return {
            appId: result.appId,
            timeStamp: result.timeStamp,
            nonceStr: result.nonceStr,
            package: result.package,
            signType: result.signType,
            paySign: result.paySign,
          }
    }
}
